import { permissionCheckResolveDecorate } from '@kuiper/auth';
import set from 'lodash/set';
import urlFormat from '../../common/urlFormat';
import errorCodesBuilder from '../helpers/errorCodesBuilder';

const errorCodes = errorCodesBuilder('资产所属权验证失败');

export default server => {
	const {
		app: { schemaComposer },
	} = server;

	schemaComposer.Mutation.addFields({
		JobOwnershipVerify: {
			description: '资产所属权验证',
			type: 'Job',
			args: {
				filter: 'FilterUpdateOneJobInput!',
				record: 'UpdateOneJobInput',
			},
			resolve: permissionCheckResolveDecorate({
				required: 'cloud-monitor\x01editJob',
				selfOnlyArgsBuilder(
					_source,
					args,
					{
						request: {
							auth: {
								credentials: { uid },
							},
						},
					}
				) {
					args.record = {};
					set(args, ['filter', 'uid'], uid);
				},
			})(async (root, { filter, record }, { request }) => {
				const {
					server: {
						methods: { domainOwnershipCheck, balanceTaskCountUpdate },
						app: {
							model: { Balance, Job },
						},
					},
				} = request;

				let job;
				let balance;
				try {
					job = await Job.findOne(filter);
					balance = await Balance.findOne({ uid: job.uid });
				} catch (err) {
					const error = errorCodes[
						'[03]所有权检查：对应Job Mongo记录查询失败'
					].from(err);
					server.log.error({ error }, error.rawMessage);
					throw error;
				}

				if (record.planExpireTime < Date.now()) {
					const error = errorCodes['[03]资产所属权验证失败：套餐已过期'];
					server.log.error({ error }, error.rawMessage);
					throw error;
				}

				let isVerified;
				if (record?.verification?.isVerified !== undefined) {
					Object.assign(job.verification, record.verification);
					isVerified = job.verification?.isVerified;
				} else {
					try {
						const {
							verification: { challenge },
							target: { protocol, hostname, port },
						} = job;
						const url = urlFormat({
							protocol,
							hostname,
							port,
						});
						isVerified = await domainOwnershipCheck({
							url: `${url}/${challenge}.txt`,
							challenge: job.verification.challenge,
						});
					} catch (err) {
						const error = errorCodes['[03]所有权检查：检查失败'].from(err);
						server.log.error({ error }, error.rawMessage);
						throw error;
					}

					job.verification.isVerified = isVerified;
					if (isVerified) {
						job.verification.verifyType = 'file';
						job.verification.verifiedTime = new Date();
					}
				}

				if (!isVerified) {
					job.enableMonitor = false;
					job.enableAlert = false;
				}

				let canAddCount =
					balance.balance.httpMaxTask.total - balance.balance.httpMaxTask.used;
				canAddCount = canAddCount < 0 ? 0 : canAddCount;
				// 去除超过套餐限制的HTTP监测任务
				if (job.httpSettings.length > canAddCount) {
					job.httpSettings = job.httpSettings.slice(0, canAddCount);
				}

				try {
					await job.save().then(() => balanceTaskCountUpdate(job.uid));
				} catch (err) {
					const error = errorCodes[
						'[03]所有权检查：对应Job Mongo记录更新失败'
					].from(err);
					server.log.error({ error }, error.rawMessage);
					throw error;
				}

				return job;
			}),
		},
	});
};
